package com.houserent.service;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.houserent.dao.AcctDao;
import com.houserent.dao.HouseDao;
import com.houserent.dao.MsgDao;
import com.houserent.dao.OrderDao;
import com.houserent.entry.AcctInfo;
import com.houserent.entry.HouseInfo;
import com.houserent.entry.HouseResult;
import com.houserent.entry.MsgInfo;
import com.houserent.entry.OrderInfo;
import com.houserent.utils.HouseUtils;

@Service
@Transactional
public class AcctServiceImpl implements AcctService {

    @Resource
    private AcctDao acctDao;
    @Resource
    private HouseDao houseDao;
    @Resource
    private OrderDao orderDao;
    @Resource
    private MsgDao msgDao;
    @Resource
    private OrderService orderService;

    // 查询历史账单信息和房间的详细信息
    @Override
    public HouseResult getAcctInfoByHouseUser(String houseId, String userId) {
        Map retMap = HouseUtils.asMap("acctInfo", "", "houseInfo", "");
        // 先查询含有入住人的sql,没有值直接查询房间的信息,由于两个方法的返回值类型不同,所以很!尴!尬!!
        Object house = houseDao.getHouseUseInfoByHouseId(houseId);
        boolean classType = false;
        if (HouseUtils.isEmpty(house)) {
            house = houseDao.getHouseInfoByHouseId(houseId);
            classType = true;
        }
        if (!HouseUtils.isEmpty(house)) {
            // 加载房间图片信息
            byte[] housepic = (byte[]) (classType ? ((HouseInfo) house).getHouse_pic() : ((Map) house).get("house_pic"));
            String picPath = HouseUtils.PIC_PATH + "pic" + houseId + ".png";
            File picFile = new File(picPath);
            if (!picFile.exists()) {
                try {
                    BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(new File(picPath)));
                    stream.write(housepic);
                    stream.close();
                }
                catch (Exception e) {
                    e.printStackTrace();
                    return new HouseResult(HouseResult.ERROR_CODE, "图片加载失败!", "");
                }
            }
            if (classType) {
                ((HouseInfo) house).setHouse_pic(picPath.substring(picPath.indexOf("/housePic") + 1));
            }
            else {
                ((Map) house).put("house_pic", picPath.substring(picPath.indexOf("/housePic") + 1));
            }
            retMap.put("houseInfo", house);
        }
        List<AcctInfo> accts = acctDao.getAcctInfoByHouseUser(HouseUtils.asMap("houseId", houseId, "userId", userId));
        if (!HouseUtils.isEmpty(accts)) {
            retMap.put("acctInfo", accts);
        }
        return new HouseResult(HouseResult.SUCCESS_CODE, "查询成功", retMap);
    }

    @Override
    public HouseResult getAcct(String userId, String userType, String orderByTag) {
        List<Map> accts = new ArrayList<Map>();
        if ("00".equals(userType)) {// 房东
            if ("4".equals(orderByTag)) {// 查询历史账单
                accts = acctDao.selectOverAcctByHostId(userId);
            }
            else {
                // orderByTag:0-房间号排序,1-到期时间,2-已付费,3-未付费
                Map dataMap = HouseUtils.asMap("userId", userId, "orderByTag", orderByTag);
                accts = acctDao.selectAcctByHostId(dataMap);
                if (HouseUtils.isEmpty(accts)) {
                    return new HouseResult(HouseResult.ERROR_CODE, "暂无账单信息", "");
                }
            }
        }
        return new HouseResult(HouseResult.SUCCESS_CODE, "查询成功", accts);
    }

    @Override
    public HouseResult optAcct(String acctId, String optType) {
        AcctInfo acct = acctDao.getAcctInfoByAcctId(acctId);
        if (HouseUtils.isEmpty(acct)) {
            return new HouseResult(HouseResult.ERROR_CODE, "未获取到账单信息", "");
        }
        if ("删除".equals(optType)) {
            // 查询状态为1和2的订单
            OrderInfo order = orderDao.selOdrerInfoByOrderId(acct.getOrder_id());
            if (!HouseUtils.isEmpty(order)) {
                return new HouseResult(HouseResult.ERROR_CODE, "该账单对应的住户尚未离开,不允许删除账单", "");
            }
            acctDao.deleteAcct(acctId);
        }
        if ("收租".equals(optType)) {
            return orderService.optOrder(acct.getOrder_id(), optType);// 给用户发送一条提醒交租的消息
        }
        if ("交租".equals(optType)) {
            // 计算下个月房租的结束时间(若是租户最后一个月,续租的结束时间也是这个)
            String endDate = HouseUtils.rollDateStr(acct.getEnd_date(), "yyyyMMddHHmmss", Calendar.MONTH, 1);

            // 1.修改账单状态
            acctDao.overAcct(acctId);
            // 2.如果是住户的最后一个月,续租并修改订单的最后交费时间 reletHouse
            OrderInfo order = orderDao.selOdrerInfoByOrderId(acct.getOrder_id());
            Map dataMap = HouseUtils.asMap("lastFeeTime", acct.getEnd_date(), "orderId", acct.getOrder_id());
            if (order.getExpect_end_date().equals(acct.getEnd_date())) {// 已经是最后一个月了
                dataMap.put("endDate", endDate);
            }
            if (1 == order.getOrder_status()) {// && HouseUtils.isBig(HouseUtils.getSysDate(),
                                               // order.getOrder_start_date())) { // 若为预定状态的订单修改为租用中
                dataMap.put("status", 2);
            }
            orderDao.reletHouse(dataMap);
            // 3.通知房东
            HouseInfo house = houseDao.getHouseInfoByHouseId(order.getHouse_id());
            String startDate = HouseUtils.TransDate(acct.getStart_date(), "yyyyMMddHHmmss", "yyyy-MM-dd");
            String feeEndDate = HouseUtils.TransDate(acct.getEnd_date(), "yyyyMMddHHmmss", "yyyy-MM-dd");
            String msgContent = "<p>亲爱的房东 : <br/><p>  您好," + house.getHouse_number() + "房间的住户已经交纳了" + startDate + "到"
                    + feeEndDate + "的房租,请确认</p>";
            MsgInfo msg = new MsgInfo();
            msg.setMsg_id(HouseUtils.createMsgID());
            msg.setAuthor_id("11111系统");
            msg.setAuthor_name("系统消息");
            msg.setUser_type("99");
            msg.setRecive_id(order.getHost_id());
            msg.setMsg_type("0");// 消息
            msg.setRead_tag("0");// 未读
            msg.setMsg_content(msgContent);
            msg.setSend_date(HouseUtils.getSysDate());
            msgDao.sendMsg(msg);
            // 4.生成下月账单
            acct.setAcct_id(HouseUtils.createAcctID());
            acct.setStart_date(acct.getEnd_date());
            acct.setEnd_date(endDate);
            acctDao.createAcct(acct);
        }
        return new HouseResult(HouseResult.SUCCESS_CODE, "操作成功", "");
    }

    @Override
    public HouseResult statistics(String hostId) {
        double[] ret = new double[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
        List<AcctInfo> accts = acctDao.getAllAcctInfoByHostId(hostId);
        if (!HouseUtils.isEmpty(accts)) {
            for (AcctInfo acct : accts) {
                if ("1".equals(acct.getPay_tag())) {// 已付费
                    int month = 0;
                    try {
                        month = HouseUtils.getDateMonth(acct.getEnd_date(), "yyyyMMddHHmmss");
                    }
                    catch (ParseException e) {
                        e.printStackTrace();
                    }
                    double fee = ret[month] + acct.getTote_fee();
                    ret[month] = fee;
                }
            }
        }

        return new HouseResult(HouseResult.SUCCESS_CODE, "统计成功", ret);
    }
}
